/**
 * @Copyright 
 * @Project inetdisk
 * @CreateTime 2015-10-23 上午10:27:37
 */
package ren.wxyz.inetdisk.util;

import org.apache.commons.lang.StringUtils;


/**
 * <p>
 * URL模式匹配，支持*.A，/A，/A*，/A/*，A*
 * </p>
 * @Author wxyz
 * @CreateTime 2015-10-23 上午10:27:37 init class
 */
public class UrlPattern {

	/**
	 * 模式字符串
	 */
	private String ptnStr;
	
	/**
	 * 开头的字符串
	 */
	private String firstStr;
	/**
	 * 结尾的字符串
	 */
	private String endStr;
	
	/**
	 * 是否是绝对路径
	 */
	private boolean isAbs;
	/**
	 * 是否仅有开头字符串
	 */
	private boolean onlyFirst;
	/**
	 * 是否仅有结尾字符串
	 */
	private boolean onlyEnd;
	
	/**
	 * <p>
	 * 创建url匹配模型
	 * </p>
	 * @param ptnStr 匹配模式字符串
	 * @CreateTime 2015-10-23 下午3:33:34 create constructor
	 */
	public UrlPattern(String ptnStr) {
		if (StringUtils.isBlank(ptnStr)) {
			throw new NullPointerException();
		}
		
		this.ptnStr = ptnStr;
		resolveUrl();
	}
	
	/**
	 * <p>
	 * 解析字符串
	 * </p>
	 * @CreateTime 2015-10-23 上午10:36:05 create method
	 */
	private void resolveUrl() {
		// 以/开头的模式，则设置绝对路径匹配
		if (this.ptnStr.startsWith("/")) {
			this.isAbs = true;
		}
		
		// 以*开头的模式，则设置
		if (this.ptnStr.startsWith("*")) {
			this.onlyEnd = true;
		}
		
		String[] items = this.ptnStr.split("\\*");
		if (this.onlyEnd) {
			this.endStr = items[items.length - 1];
		}
		else if (items.length == 1) {
			this.onlyFirst = true;
			this.firstStr = items[0];
		}
		else {
			this.firstStr = items[0];
			this.endStr = items[items.length - 1];
		}
	}
	
	/**
	 * <p>
	 * 检查给定url是否本模式
	 * </p>
	 * @param url 给定的待检查的url
	 * @return
	 * @CreateTime 2015-10-23 上午11:16:34 create method
	 */
	public boolean match(String url) {
		if (StringUtils.isBlank(url)) {
			return false;
		}
		
		// 只有开头
		if (this.onlyFirst) {
			// 绝对路径，则url的开头必须是首字符串，否则，只需包含即可
			if (this.isAbs) {
				return url.startsWith(this.firstStr);
			}
			else {
				return url.contains(this.firstStr);
			}
		}
		
		// 只有结尾
		if (this.onlyEnd) {
			return url.endsWith(this.endStr);
		}
		
		// 开头和结尾都有
		if (!this.onlyFirst && !this.onlyEnd) {
			if (isAbs) {
				return url.startsWith(this.firstStr) && url.endsWith(this.endStr);
			}
			else {
				return url.contains(this.firstStr) && url.endsWith(this.endStr);
			}
		}
		
		return false;
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof UrlPattern) {
			UrlPattern ptn = (UrlPattern) obj;
			
			return ptn.ptnStr.equals(this.ptnStr);
		}
		
		return false;
	}
}
